﻿using Authentication.Configuration;
using Authentication.Model.Model;
using Common.Contract;
using Common.Contract.Authentication;
using Common.Contract.Authentication.Record;
using Common.Contract.Authentication.Request;
using Common.Service;
using Common.Type;
using Common.Util;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq;
using Common.Cache;
using Common.Service.DataTables;
using Common.Contract.Paging;
using Authentication.Model.ViewModel.Account;
using Authentication.Model.ViewModel.System;
using System;
using Common.Contract.Customer.Request;
using Common.Contract.Customer;
using Common.Contract.Customer.Record;
using Common.Contract.Customer.Response;
using Common.Contract.SaleOut;

namespace Authentication.Web.Controller
{
    public class SystemController : ControllerBase
    {
        #region Menu & header
        [Authorize]
        [ChildActionOnly]
        public ActionResult HeaderInfor()
        {
            return PartialView("_Header", this.CurrentUser);
        }

        [Authorize]
        [ChildActionOnly]
        public ActionResult SysMenu()
        {
            var nodes = this.MenuNodes;
            return PartialView("_Menu", nodes);
        }
        #endregion

        #region Roles
        [Authorize]
        public ActionResult Roles()
        {
            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                RetrieveObjectsRequest request = new RetrieveObjectsRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.Index"
                    }
                };
                var xx = serviceClient.Proxy.RetrieveObjects(request);
                var yy = xx.Page.TotalRecords;
            }

            RoleViewModel vm = new RoleViewModel { IsSupperAdmin = CurrentUser.Equals(SystemConfiguration.SUPPER_ADMIN, StringComparison.OrdinalIgnoreCase) };
            return View(vm);
        }

        [HttpPost]
        [Authorize]
        public ActionResult Roles(RoleViewModel vm)
        {
            var header = new RequestHeaderRecord
            {
                ApplicationKey = SystemConfiguration.ApplicationKey,
                CallerName = "Authentication.Web.Controller.SystemController.Roles"
            };

            var record = new RoleRecord
            {
                ApplicationKey = SystemConfiguration.ApplicationKey,
                RoleIdentifier = vm.RoleIdentifier,
                Name = vm.RoleName,
                Description = vm.Description,
                Active = vm.Active
            };

            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                ResponseRecord response = null;
                if (string.IsNullOrWhiteSpace(vm.RoleIdentifier))
                {
                    AddRoleRequest request = new AddRoleRequest
                    {
                        Header = header,
                        Record = record
                    };
                    response = serviceClient.Proxy.AddRole(request);
                }
                else
                {
                    UpdateRoleRequest request = new UpdateRoleRequest
                    {
                        Header = header,
                        Record = record
                    };
                    response = serviceClient.Proxy.UpdateRole(request);
                }

                if (response.IsSuccess)
                {
                    return RedirectToAction("roles", "system");
                }
                else
                {
                    vm.Message = response.ErrorMessage;
                    vm.MessageType = MessageType.Error;
                    vm.IsSupperAdmin = CurrentUser.Equals(SystemConfiguration.SUPPER_ADMIN, StringComparison.OrdinalIgnoreCase);
                }
            }
            return View(vm);
        }

        [Authorize]
        [HttpPost]
        public ActionResult Delete_Role(string code)
        {
            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                DeleteRoleRequest request = new DeleteRoleRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.Roles"
                    },
                    Record = code
                };
                var response = serviceClient.Proxy.DeleteRole(request);
                return Json(response);
            }
        }

        [HttpPost]
        [Authorize]
        public ActionResult RolesData(DataTablesPageRequest pageRequest)
        {
            DataTableResponse pageResponse = null;
            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                SearchRolesRequest request = new SearchRolesRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.RolesData"
                    },
                    Page = new PageRecord
                    {
                        PageSize = pageRequest.DisplayLength,
                        PageIndex = pageRequest.DisplayLength > 0 ? pageRequest.DisplayStart / pageRequest.DisplayLength : 0
                    },
                    Name = pageRequest.Search.Trim()
                };
                var applicationRecord = serviceClient.Proxy.SearchRoles(request);
                var resultApplication = (applicationRecord == null || applicationRecord.Records == null) ? new List<RoleRecord>() : applicationRecord.Records;
                pageResponse = new DataTableResponse
                {
                    sEcho = pageRequest.Echo,
                    iTotalRecords = applicationRecord.Page.TotalRecords,
                    sColumns = pageRequest.ColumnNames,
                    aaData = resultApplication.Select(x => new object[]{x.RoleIdentifier, 
                                                             x.Name,
                                                             x.Description,
                                                             x.Active,
                                                             true}).ToList()
                };
            }
            return Json(pageResponse);
        }
        #endregion

        #region Objects
        [Authorize]
        public ActionResult Objects()
        {
            ObjectViewModel vm = new ObjectViewModel { IsSupperAdmin = CurrentUser.Equals(SystemConfiguration.SUPPER_ADMIN, StringComparison.OrdinalIgnoreCase) };
            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                RetrieveObjectsRequest request = new RetrieveObjectsRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.Index"
                    }
                };
                var xx = serviceClient.Proxy.RetrieveObjects(request);
                if (xx.IsSuccess)
                {
                    //var yy = xx.Page.TotalRecords;
                    vm.Objects = xx.Records;
                }
            }
            return View(vm);
        }

        [HttpPost]
        [Authorize]
        public ActionResult Objects(ObjectViewModel vm, string btnClick)
        {
            vm.IsSupperAdmin = CurrentUser.Equals(SystemConfiguration.SUPPER_ADMIN, StringComparison.OrdinalIgnoreCase);
            var record = new ObjectRecord
            {
                ApplicationKey = SystemConfiguration.ApplicationKey,
                ObjectIdentifier = vm.ObjectIdentifier,
                ParentIdentifier = vm.ParentIdentifier,
                ObjectName = vm.ObjectName,
                ObjectUrl = vm.ObjectUrl,
                ObjectIcon = vm.Icon,
                IsSubstitution = vm.IsSubstitution
            };

            var header = new RequestHeaderRecord
            {
                ApplicationKey = SystemConfiguration.ApplicationKey,
                CallerName = "Authentication.Web.Controller.SystemController.Objects"
            };

            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                RetrieveObjectsRequest requestObjects = new RetrieveObjectsRequest { Header = header };
                var responseObjects = serviceClient.Proxy.RetrieveObjects(requestObjects);
                if (responseObjects.IsSuccess)
                {
                    vm.Objects = responseObjects.Records;
                }

                if (vm.IsSubstitution && vm.ParentIdentifier.IsNullOrWhiteSpace())
                {
                    vm.Message = "You must put a control in to a menu item";
                    vm.MessageType = MessageType.Error;
                    return View(vm);
                }

                ResponseRecord response = null;
                if (btnClick.Equals("btnNewObject", System.StringComparison.OrdinalIgnoreCase))
                {
                    AddObjectRequest request = new AddObjectRequest
                    {
                        Header = header,
                        Record = record
                    };
                    response = serviceClient.Proxy.AddObject(request);
                }
                else
                {

                    UpdateObjectRequest request = new UpdateObjectRequest
                    {
                        Header = header,
                        Record = record
                    };
                    response = serviceClient.Proxy.UpdateObject(request);
                }


                if (response != null || response.IsSuccess)
                {
                    CacheFactory.MemCache.RemoveFromCache(string.Format(CACHING_NAME.CURRENT_USER_OBJECT, this.CurrentUser), true);
                    return RedirectToAction("objects", "system");
                }
                else
                {
                    vm.Message = response.ErrorMessage;
                    vm.MessageType = MessageType.Error;
                }
            }
            return View(vm);
        }


        [Authorize]
        [HttpPost]
        public ActionResult Delete_Object(string code)
        {
            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                DeleteObjectRequest request = new DeleteObjectRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.Objects"
                    },
                    Record = code
                };
                var response = serviceClient.Proxy.DeleteObject(request);
                if (response.IsSuccess)
                {
                    CacheFactory.MemCache.RemoveFromCache(string.Format(CACHING_NAME.CURRENT_USER_OBJECT, this.CurrentUser), true);
                }

                return Json(response);
            }
        }

        [HttpPost]
        [Authorize]
        public ActionResult ObjectsData(DataTablesPageRequest pageRequest)
        {
            DataTableResponse pageResponse = null;
            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                RetrieveObjectsRequest request = new RetrieveObjectsRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.ObjectsData"
                    },
                    Name = pageRequest.Search.Trim(),
                    Page = new PageRecord
                    {
                        PageSize = pageRequest.DisplayLength,
                        PageIndex = pageRequest.DisplayLength > 0 ? pageRequest.DisplayStart / pageRequest.DisplayLength : 0
                    }
                };

                var response = serviceClient.Proxy.RetrieveObjects(request);
                var resultApplication = (response == null || response.Records == null) ? new List<ObjectRecord>() : response.Records;
                pageResponse = new DataTableResponse
                {
                    sEcho = pageRequest.Echo,
                    iTotalRecords = response.Page.TotalRecords,
                    sColumns = pageRequest.ColumnNames,
                    aaData = resultApplication.Select(x => new object[]{x.ObjectIdentifier, 
                                                             x.ParentIdentifier??string.Empty,
                                                             x.ObjectIcon??string.Empty,
                                                             x.ObjectName,
                                                             x.ObjectUrl??string.Empty,
                                                             x.IsSubstitution??false
                                                             }).ToList()
                };
            }
            return Json(pageResponse);
        }
        #endregion

        #region Applications

        [HttpGet]
        [Authorize]
        public ActionResult Applications()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ApplicationData(DataTablesPageRequest pageRequest)
        {
            DataTableResponse pageResponse = null;
            using (ServiceClient<IAuthentication> serviceClient = new ServiceClient<IAuthentication>())
            {
                SearchApplicationsRequest request = new SearchApplicationsRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.ApplicationData"
                    },
                    Page = new PageRecord
                    {
                        PageSize = pageRequest.DisplayLength,
                        PageIndex = pageRequest.DisplayLength > 0 ? pageRequest.DisplayStart / pageRequest.DisplayLength : 0
                    },
                    Name = pageRequest.Search.Trim()
                };
                var applicationRecord = serviceClient.Proxy.SearchApplications(request);
                var resultApplication = (applicationRecord == null || applicationRecord.Records == null) ? new List<ApplicationRecord>() : applicationRecord.Records;
                pageResponse = new DataTableResponse
                {
                    sEcho = pageRequest.Echo,
                    iTotalRecords = applicationRecord.Page.TotalRecords,
                    sColumns = pageRequest.ColumnNames,
                    aaData = resultApplication.Select(x => new object[]{x.ApplicationKey, 
                                                             x.Name,
                                                             x.CreationDate,
                                                             x.UpdateDate,
                                                             x.Description}).ToList()
                };
            }
            return Json(pageResponse);
        }
        #endregion


        #region Autocomplete Region, Province, District
        [HttpPost]
        [Authorize]
        [OutputCache(Duration = 10)]
        public ActionResult RegionsTerm(string code)
        {
            SearchRegionsResponse response = null;
            using (ServiceClient<ICustomer> serviceClient = new ServiceClient<ICustomer>())
            {
                SearchRegionsRequest request = new SearchRegionsRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.RegionsTerm"
                    },
                    Page = new PageRecord { PageSize = 100 },
                    TextSearch = (code ?? string.Empty).Trim()
                };
                response = serviceClient.Proxy.SearchRegions(request);
                return Json(response);
            }
        }


        [HttpPost]
        [Authorize]
        [OutputCache(Duration = 10)]
        public ActionResult ProvincesTerm(string term, string region)
        {
            SearchProvincesResponse response = null;
            using (ServiceClient<ICustomer> serviceClient = new ServiceClient<ICustomer>())
            {
                SearchProvincesRequest request = new SearchProvincesRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.ProvincesTerm"
                    },
                    Page = new PageRecord { PageSize = 100 },
                    ProvinceName = (term ?? string.Empty).Trim(),
                    RegionIdentifier = region
                };
                response = serviceClient.Proxy.SearchProvinces(request);
                return Json(response);
            }
        }


        [HttpPost]
        [Authorize]
        [OutputCache(Duration = 10)]
        public ActionResult DistrictsTerm(string term, string province)
        {
            SearchDistrictsResponse response = null;
            using (ServiceClient<ICustomer> serviceClient = new ServiceClient<ICustomer>())
            {
                SearchDistrictsRequest request = new SearchDistrictsRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.DistrictsTerm"
                    },
                    Page = new PageRecord { PageSize = 100 },
                    DistrictName = (term ?? string.Empty).Trim(),
                    ProvinceIdentifier = province
                };
                response = serviceClient.Proxy.SearchDistricts(request);
                return Json(response);
            }
        }


        [HttpPost]
        [Authorize]
        [OutputCache(Duration = 10)]
        public ActionResult BillToTerm(string term)
        {
            SearchBilltoInfResponse response = null;
            using (ServiceClient<ISaleOut> serviceClient = new ServiceClient<ISaleOut>())
            {
                SearchBilltoInfRequest request = new SearchBilltoInfRequest
                {
                    Header = new RequestHeaderRecord
                    {
                        ApplicationKey = SystemConfiguration.ApplicationKey,
                        CallerName = "Authentication.Web.Controller.SystemController.DistrictsTerm"
                    },
                    TextSearch = (term ?? string.Empty).Trim()
                };
                response = serviceClient.Proxy.SearchBillTo(request);
                return Json(response);
            }
        }
        #endregion
    }
}
